package com.copa.module.user.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.copa.domain.PageVo;
import com.copa.domain.ResponseDto;
import com.copa.module.order.domain.dto.OrderListDto;
import com.copa.module.user.domain.dto.UserLoginDTO;
import com.copa.module.user.domain.entity.CustomerUserEntity;
import com.copa.module.user.domain.entity.UserEntity;
import com.copa.module.user.domain.vo.UserListVo;
import com.copa.module.user.domain.vo.UserLoginVO;
import com.copa.module.user.domain.vo.UserUpdateVo;
import com.copa.module.user.mapper.UserDao;
import com.copa.module.user.service.UserService;
import com.copa.module.user.manage.UserRoleManage;
import com.copa.utils.JwtTokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author copa
 * @createDate 2021-01-05 8:35
 * @function
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private UserRoleManage userRoleManage;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenUtils jwtTokenUtils;

    @Override
    public ResponseDto<IPage<UserEntity>> list(UserListVo userListVo) {
//        IPage<UserEntity> userEntities = userDao.selectPage(new Page<>(pageVO.getCurrent(), pageVO.getSize()), null);
        Page<UserEntity> page = new Page<>(userListVo.getPageVo().getCurrent(), userListVo.getPageVo().getSize());

        IPage<UserEntity> userEntities = userDao.findUserListByUserListVo(page, userListVo);

        if (ObjectUtil.isNotNull(userEntities)) {
            return ResponseDto.success(userEntities);
        }
        return ResponseDto.errorMsg("抱歉，没查到该用户信息！");
    }

    @Override
    public ResponseDto<UserEntity> findByUsername(String username) {
        UserEntity userEntity = userDao.findByUsername(username);
        if (ObjectUtil.isNotNull(userEntity)) {
            return ResponseDto.success(userEntity);
        }
        return ResponseDto.errorMsg("抱歉，没查到该用户信息！");
    }

    @Override
    public ResponseDto<UserLoginDTO> login(UserLoginVO userLoginVO) {
        // 通过用户名和密码创建一个 Authentication 认证对象，实现类为 UsernamePasswordAuthenticationToken
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userLoginVO.getUsername(), userLoginVO.getPassword());

        try {
            //通过 AuthenticationManager（默认实现为ProviderManager）的authenticate方法验证 Authentication 对象
            Authentication authentication = authenticationManager.authenticate(authenticationToken);
            CustomerUserEntity principal = (CustomerUserEntity) authentication.getPrincipal();
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(principal.getUser(), null, authentication.getAuthorities());

            //将 Authentication 绑定到 SecurityContext
            SecurityContextHolder.getContext().setAuthentication(authentication);
            //生成Token
            String token = jwtTokenUtils.createToken(authentication);

            ResponseDto<UserLoginDTO> resMsg = userRoleManage.findUserByUsernameAndPassword(principal.getUser().getId());
            if (resMsg.isNotSuccess()) {
                return resMsg;
            }
            UserLoginDTO userLoginDTO = resMsg.getData();
            userLoginDTO.setToken("Bearer " + token);
            return ResponseDto.success(userLoginDTO);

        } catch (BadCredentialsException authentication) {
            return ResponseDto.errorCodeMsg(401,"Login failed");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseDto<String> updateIsEnable(UserUpdateVo userUpdateVo) {
        Boolean flag = userDao.updateIsEnableByUserId(userUpdateVo);
        if (flag) {
            return ResponseDto.successMsg("修改成功");
        }
        return ResponseDto.errorMsg("系统繁忙，请稍后再试");
    }
}
